/*
 * @FilePath: 球体贴图.js
 * @Author: 杜芬
 * @Date: 2024-04-15 21:59:33
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2024-04-16 11:25:53
 * Copyright: 2024 xxxTech CO.,LTD. All Rights Reserved.
 * @Descripttion: 球体贴图1
 * // 目标3：基础网格材质-透明度贴图
// 作用：让物体某些部分透明
// 原理：借助透明度贴图（黑色部分：完全透明，白色部分：完全不透明）-> 用颜色计算像素点透明度，因为黑色是 0
// 注意：材质需要开启 transparent 属性
// 与 opacity 区别：
//  透明度贴图部分透明
//  opactity 全都透明
// 步骤：
// 1. 创建透明度贴图纹理对象
// 2. 传入透明纹理对象
// 3. 开启透明材质
 */
// 目标3：基础网格材质-环境遮挡贴图
// 作用：让物体有亮暗的对比，更真实
// 原理：黑色部分挡住光线（更暗），白色部分（更亮）
// 步骤：
// 1. 创建纹理对象，加载贴图
// 2. 赋予给材质 aoMap 属性

// 目标4：Lambert 网格材质
// 作用：一种非光泽表面的材质（漫反射），没有镜面高光（受光照影响）
// 使用：
// 1. 替换网格材质的构造函数为 MeshLambertMaterial
// 2. 设置平行光 DirectionalLight 照亮物体
// 注意：ao 环境遮挡贴图只对"环境光"做计算

// 目标4：Phong 网格材质
// 作用：一种具有镜面高光，光泽表面材质（受光照影响）
// 使用：替换网格材质的构造函数为 MeshPhongMaterial

import {scene} from './utils/init.js'

import * as THREE from 'three'
import { Mesh } from 'three'

function initBase() {
  // 1. 创建几何图形
  const geometry = new THREE.SphereGeometry(1, 32, 16)

  // 2.定义纹理对象（图片）
  const textureLoader = new THREE.TextureLoader()
  const texture = textureLoader.load('/texture/one/basecolor.jpg')
  texture.colorSpace = THREE.SRGBColorSpace

  
  // 2-1 创建透明度贴图纹理对象
  const alphaTexture = textureLoader.load('/texture/one/opacity.jpg')
  // 颜色较浅时设置colorSpace
  alphaTexture.colorSpace = THREE.SRGBColorSpace

  // 3-1环境遮挡贴图
  const aoTexture = textureLoader.load('/texture/one/ambientOcclusion.jpg')
  aoTexture.colorSpace = THREE.SRGBColorSpace
  // 3.创建网格材质，装入纹理
  // const material = new THREE.MeshBasicMaterial({
  //   map:texture,
  //   // alphaMap:alphaTexture, // 2-2传入透明纹理对象
  //   // transparent:true, //2-3开启透明材质
  //   // opacity:0.1 // opacity透明度 ：全透明。透明纹理贴图部分透明
  //   aoMap:aoTexture // 设置环境遮挡贴图的纹理对象

  // })
  // const material = new THREE.MeshLambertMaterial({
  //   map:texture,
  //   // alphaMap:alphaTexture, // 2-2传入透明纹理对象
  //   // transparent:true, //2-3开启透明材质
  //   // opacity:0.1 // opacity透明度 ：全透明。透明纹理贴图部分透明
  //   aoMap:aoTexture // 设置环境遮挡贴图的纹理对象

  // })

  // 目标：Phong 网格材质
// 作用：一种具有镜面高光，光泽表面材质（受光照影响）
// 使用：替换网格材质的构造函数为 MeshPhongMaterial

// const material = new THREE.MeshPhongMaterial({
//   map:texture,
//   // alphaMap:alphaTexture, // 2-2传入透明纹理对象
//   // transparent:true, //2-3开启透明材质
//   // opacity:0.1 // opacity透明度 ：全透明。透明纹理贴图部分透明
//   aoMap:aoTexture, // 设置环境遮挡贴图的纹理对象
//   shininess:100 // 光照亮度

// })
// 目标：标准网格材质 - 粗糙度和贴图
// 定义：一种基于物理渲染（PBR）的标准材质
// 作用：除了比前两种材质受光照影响外，可以设置粗糙度
// 使用：替换网格材质的构造函数为 MeshStandardMaterial
// 粗糙度贴图原理：黑色（光滑，高光），白色（粗糙，不反光，散射）


// 粗糙度贴图
const roughnessTexture = textureLoader.load('/texture/one/roughness.jpg')
roughnessTexture.colorSpace = THREE.SRGBColorSpace

// 金属度贴图
const  metalnessTexture = textureLoader.load('/texture/one/metalness.jpg')
metalnessTexture.colorSpace = THREE.SRGBColorSpace

// 位移贴图
const displacementTexture = textureLoader.load('/texture/one/displace_height.jpg')
displacementTexture.colorSpace = THREE.SRGBColorSpace

// 法线贴图
const normalTexture = textureLoader.load('/texture/one/normal.jpg')
normalTexture.colorSpace = THREE.SRGBColorSpace

const material = new THREE.MeshStandardMaterial({
  map:texture,
  // alphaMap:alphaTexture, // 2-2传入透明纹理对象
  // transparent:true, //2-3开启透明材质
  // opacity:0.1 // opacity透明度 ：全透明。透明纹理贴图部分透明
  // aoMap:aoTexture, // 设置环境遮挡贴图的纹理对象
  // shininess:100 // 光照亮度
  roughness: 1, //  粗糙设置( 0 光滑， 1 粗糙)
  roughnessMap:roughnessTexture , // 粗糙度贴图 同时设置上个属性建议为 1
  metalness:1 ,// 金属度(反光射的程度，1 是最高)
  metalnessMap:metalnessTexture, // 金属度贴图
  displacementMap:displacementTexture ,  //  // 位移贴图
  displacementScale:0.2 , // 位移范围(0-1) 1 最大
  normalMap:normalTexture // // 法线贴图(影响光照)


})


  // 4.生成物体加入到场景中
  const mesh = new THREE.Mesh(geometry, material)
  
// 扩展：给目标物体设置第二组UV坐标（影响贴图像素点转换对应映射过程）
// 当aomap 直接无结果的时候，设置第二组 uv 坐标来影响贴图贴过来时的明暗效果
   mesh.geometry.setAttribute('uv2',new THREE.BufferAttribute(mesh.geometry.attributes.uv.array,2))
   console.log(mesh)
  scene.add(mesh)
}

function createLight() {
  // 平行光：从一个方向发射过来的平行光线

 const direction = new THREE.DirectionalLight(0xffffff, 2) // 创建光源
 direction.position.set(3, 3, 3) // 设置光源的位置

  // 环境光：无方向，照亮场景中所有受光照影响的物体
 const light = new THREE.AmbientLight( 0xffffff, ); // 柔和的白光
//  加入到场景中
scene.add( light );

//  平行光辅助对象
//  参数1： 平行光对象 参数2：模拟光源的大小
const helper = new THREE.DirectionalLightHelper( direction, 5 );
scene.add( helper );


 // 将光源加入到场景中
 scene.add(direction)

}
initBase()
createLight() 